package com.bobo.web.provider.util.commutils;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 业务单号生成工具类
 */
public class GeneralNumUtil {
	/**
	 * 订单编号前缀
	 */
	private static final String ORDER_CODE = "M2U";
	/**
	 * 锁对象
	 */
	private static final Lock LOCK = new ReentrantLock();
	/**
	 * 机器码,修改为随机数
	 */
	private static String machineCode=IpAddrUtil.generateIp();

	/**
	 * 自增序列
	 */
	private static AtomicLong atomicLong = new AtomicLong();

	/**
	 * 记录最近一次时间戳
	 */
	private static volatile Long lastTime = 0L;
	/**
	 * 生成支付订单号
	 * @return
	 */
	public static String getOrderCode() {
		return getGeneralNum(ORDER_CODE);
	}


	/**
	 * 根据前缀生成业务单号
	 * @param prefix
	 * @return
	 */
	public static String getGeneralNum(String prefix){
		LOCK.lock();
		try {
			lastTime = timeGen();

			if(atomicLong.intValue() > 998){
				atomicLong.set(0);
				lastTime = tilNextMillis(lastTime);
			}

			return prefix + machineCode + lastTime + String.format("%03d", atomicLong.incrementAndGet());
		} finally {
			LOCK.unlock();
		}
	}

	/**
	 * 获取下一毫秒时间戳
	 * @param lastTimestamp
	 * @return
	 */
	private static long tilNextMillis(final long lastTimestamp) {
		long timestamp = timeGen();

		while (timestamp <= lastTimestamp) {
			timestamp = timeGen();
		}

		return timestamp;
	}

	/**
	 * 获取时间戳
	 * @return
	 */
	private static long timeGen() {
		return System.currentTimeMillis();
	}


	public static void main(String[] args) {
		long l = System.currentTimeMillis();
		for (int i=0; i<10; i++){
			System.out.println(getGeneralNum(""));
		}
		System.out.println("========" + (System.currentTimeMillis()-l));
	}
}
